home *** CD-ROM | disk | FTP | other *** search
/ PCMania 81 / PCMania CD81_1.iso / PCMANIA / demosc81 / AFFINE.C next >
C/C++ Source or Header  |  1999-04-22  |  9KB  |  331 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. //  This structs are used for the matrix maths related with the affine     //
  4. //  transformations of objects & camera. In 3d_math you will find the      //
  5. //  functions related to inversion & combination of affine transformations //
  6. //                                                                         //
  7. /////////////////////////////////////////////////////////////////////////////
  8.  
  9. #include <math.h>
  10.  
  11. float pi=3.141592654;
  12.  
  13. typedef struct matrix
  14. {
  15.  float m11,m21,m31,m12,m22,m32,m13,m23,m33;
  16. }MATRIX;
  17.  
  18. typedef struct vector
  19. {
  20.  float v1,v2,v3;
  21. }VECTOR;
  22.  
  23. typedef struct vector2d
  24. {
  25.  float v1,v2;
  26. }VECTOR2D;
  27.  
  28. typedef struct affin
  29. {
  30.  MATRIX aff_mtx;
  31.  VECTOR aff_vtr;
  32. }AFFIN;
  33.  
  34. typedef struct implicit_plane
  35. {
  36.  VECTOR normal;
  37.  float d;
  38. }IMPLICIT_PLANE;
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. //                                                                         //
  42. //  Various functions used for the matrix maths related with the affine    //
  43. //  transformations of objects & camera. In 3d_strc you will find the      //
  44. //  prototypes for the matrix, vector & aff_trns structures.               //
  45. //                                                                         //
  46. /////////////////////////////////////////////////////////////////////////////
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. //  This function gets the Determinant of an 3x3 matrix, as is defined in  //
  50. //  3d_strc. It returns a float.                                           //
  51. /////////////////////////////////////////////////////////////////////////////
  52.  
  53. float det_mtx(MATRIX source)
  54. {
  55.  float res;
  56.  res=(source.m11*(source.m22*source.m33-source.m23*source.m32)+
  57.       source.m12*(source.m23*source.m31-source.m21*source.m33)+
  58.       source.m13*(source.m21*source.m32-source.m22*source.m31));
  59.  return(res);
  60. }
  61.  
  62. /////////////////////////////////////////////////////////////////////////////
  63. //  This function gets the Inverse of an 3x3 matrix. The result is another //
  64. //  3x3 matrix. This routine may fail if Det(source) is equal to 0, but    //
  65. //  this is impossible working with standard 3D rotation matrixes          //
  66. /////////////////////////////////////////////////////////////////////////////
  67.  
  68. MATRIX inv_mtx(MATRIX source)
  69. {
  70.  MATRIX res;
  71.  float  det;
  72.  det=1/det_mtx(source);
  73.  res.m11=det*(source.m22*source.m33-source.m23*source.m32);
  74.  res.m12=det*(source.m13*source.m32-source.m12*source.m33);
  75.  res.m13=det*(source.m12*source.m23-source.m13*source.m22);
  76.  
  77.  res.m21=det*(source.m23*source.m31-source.m21*source.m33);
  78.  res.m22=det*(source.m11*source.m33-source.m13*source.m31);
  79.  res.m23=det*(source.m13*source.m21-source.m11*source.m23);
  80.  
  81.  res.m31=det*(source.m21*source.m32-source.m22*source.m31);
  82.  res.m32=det*(source.m12*source.m31-source.m11*source.m32);
  83.  res.m33=det*(source.m11*source.m22-source.m12*source.m21);
  84.  return(res);
  85. }
  86.  
  87. /////////////////////////////////////////////////////////////////////////////
  88. // This function gets Composition of two 3x3 matrix. The result is another //
  89. // 3x3 matrix. Warning: matrix composition is not commutative!!!           //
  90. /////////////////////////////////////////////////////////////////////////////
  91.  
  92. MATRIX mtx_mul_mtx(MATRIX a, MATRIX b)
  93. {
  94.  MATRIX res;
  95.  res.m11=a.m11*b.m11+a.m21*b.m12+a.m31*b.m13;
  96.  res.m21=a.m11*b.m21+a.m21*b.m22+a.m31*b.m23;
  97.  res.m31=a.m11*b.m31+a.m21*b.m32+a.m31*b.m33;
  98.  
  99.  res.m12=a.m12*b.m11+a.m22*b.m12+a.m32*b.m13;
  100.  res.m22=a.m12*b.m21+a.m22*b.m22+a.m32*b.m23;
  101.  res.m32=a.m12*b.m31+a.m22*b.m32+a.m32*b.m33;
  102.  
  103.  res.m13=a.m13*b.m11+a.m23*b.m12+a.m33*b.m13;
  104.  res.m23=a.m13*b.m21+a.m23*b.m22+a.m33*b.m23;
  105.  res.m33=a.m13*b.m31+a.m23*b.m32+a.m33*b.m33;
  106.  return(res);
  107. }
  108.  
  109. /////////////////////////////////////////////////////////////////////////////
  110. // This function gets Composition of an 3x3 matrix with a vector. Returns  //
  111. // another vector. It's impossible to make the composition between one     //
  112. // vector and one matrix.                                                  //
  113. /////////////////////////////////////////////////////////////////////////////
  114.  
  115. VECTOR mtx_mul_vtr(MATRIX a, VECTOR b)
  116. {
  117.  VECTOR res;
  118.  res.v1=a.m11*b.v1+a.m21*b.v2+a.m31*b.v3;
  119.  res.v2=a.m12*b.v1+a.m22*b.v2+a.m32*b.v3;
  120.  res.v3=a.m13*b.v1+a.m23*b.v2+a.m33*b.v3;
  121.  return(res);
  122. }
  123.  
  124. /////////////////////////////////////////////////////////////////////////////
  125. // This function simply changes the sign of a vector.                      //
  126. /////////////////////////////////////////////////////////////////////////////
  127.  
  128. VECTOR neg_vtr(VECTOR source)
  129. {
  130.  VECTOR res;
  131.  res.v1=-source.v1;
  132.  res.v2=-source.v2;
  133.  res.v3=-source.v3;
  134.  return(res);
  135. }
  136.  
  137. /////////////////////////////////////////////////////////////////////////////
  138. // This function just add 2 vectors.                                       //
  139. /////////////////////////////////////////////////////////////////////////////
  140.  
  141. VECTOR vtr_add_vtr(VECTOR a, VECTOR b)
  142. {
  143.  VECTOR res;
  144.  res.v1=a.v1+b.v1;
  145.  res.v2=a.v2+b.v2;
  146.  res.v3=a.v3+b.v3;
  147.  return(res);
  148. }
  149.  
  150. VECTOR vtr_sub_vtr(VECTOR a, VECTOR b)
  151. {
  152.  VECTOR res;
  153.  res.v1=a.v1-b.v1;
  154.  res.v2=a.v2-b.v2;
  155.  res.v3=a.v3-b.v3;
  156.  return(res);
  157. }
  158.  
  159. VECTOR mul_vtr(float a, VECTOR b)
  160. {
  161.  VECTOR res;
  162.  res.v1=a*b.v1;
  163.  res.v2=a*b.v2;
  164.  res.v3=a*b.v3;
  165.  return(res);
  166. }
  167.  
  168.  
  169. VECTOR vtr_cross_mul_vtr(VECTOR a, VECTOR b)
  170. {
  171.  VECTOR res;
  172.  res.v1=a.v2*b.v3-a.v3*b.v2;
  173.  res.v2=a.v3*b.v1-a.v1*b.v3;
  174.  res.v3=a.v1*b.v2-a.v2*b.v1;
  175.  return(res);
  176. }
  177.  
  178. VECTOR vtr_dir_mul_vtr(VECTOR a, VECTOR b)
  179. {
  180.  VECTOR res;
  181.  res.v1=a.v1*b.v1;
  182.  res.v2=a.v2*b.v2;
  183.  res.v3=a.v3*b.v3;
  184.  return(res);
  185. }
  186.  
  187. float vtr_dot_mul_vtr(VECTOR a, VECTOR b)
  188. {
  189.  float res;
  190.  res=a.v1*b.v1+a.v2*b.v2+a.v3*b.v3;
  191.  return(res);
  192. }
  193.  
  194. float vtr_mix_mul(VECTOR a, VECTOR b, VECTOR c)
  195. {
  196.  return(vtr_dot_mul_vtr(a,vtr_cross_mul_vtr(b,c)));
  197. }
  198.  
  199. float mod_vtr(VECTOR a)
  200. {
  201.  return(sqrt(a.v1*a.v1+a.v2*a.v2+a.v3*a.v3));
  202. }
  203.  
  204. VECTOR unit_vtr(VECTOR a)
  205. {
  206.  float res;
  207.  res=mod_vtr(a);
  208.  if (res!=0)
  209.  {
  210.   res=1/res;
  211.   a.v1*=res;
  212.   a.v2*=res;
  213.   a.v3*=res;
  214.  }
  215.  else
  216.  {
  217.   a.v1=0;
  218.   a.v2=0;
  219.   a.v3=1;
  220.  }
  221.  return (a);
  222. }
  223.  
  224. VECTOR divide_vtr(VECTOR a,float b)
  225. {
  226.  float res;
  227.  if (b!=0)
  228.  {
  229.   res=1/b;
  230.   a.v1*=res;
  231.   a.v2*=res;
  232.   a.v3*=res;
  233.  }
  234.  else
  235.  {
  236.   a.v1=0;
  237.   a.v2=0;
  238.   a.v3=1;
  239.  }
  240.  return (a);
  241. }
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. //  This function gets the Inverse of an affine transformation. The result //
  245. //  It returns another affine transformation.                              //
  246. /////////////////////////////////////////////////////////////////////////////
  247.  
  248.  
  249.  
  250. AFFIN inv_aff(AFFIN source)
  251. {
  252.  AFFIN res;
  253.  res.aff_mtx=inv_mtx(source.aff_mtx);
  254.  res.aff_vtr=mtx_mul_vtr(res.aff_mtx,neg_vtr(source.aff_vtr));
  255.  return(res);
  256. }
  257.  
  258. MATRIX i_mtx(MATRIX source)
  259. {
  260.  MATRIX res;
  261.  res.m11=source.m22*source.m33-source.m23*source.m32;
  262.  res.m12=source.m13*source.m32-source.m12*source.m33;
  263.  res.m13=source.m12*source.m23-source.m13*source.m22;
  264.  
  265.  res.m21=source.m23*source.m31-source.m21*source.m33;
  266.  res.m22=source.m11*source.m33-source.m13*source.m31;
  267.  res.m23=source.m13*source.m21-source.m11*source.m23;
  268.  
  269.  res.m31=source.m21*source.m32-source.m22*source.m31;
  270.  res.m32=source.m12*source.m31-source.m11*source.m32;
  271.  res.m33=source.m11*source.m22-source.m12*source.m21;
  272.  return(res);
  273. }
  274.  
  275.  
  276. AFFIN i_aff(AFFIN source)
  277. {
  278.  AFFIN res;
  279.  res.aff_mtx=i_mtx(source.aff_mtx);
  280.  res.aff_vtr=mtx_mul_vtr(res.aff_mtx,neg_vtr(source.aff_vtr));
  281.  return(res);
  282. }
  283.  
  284. /////////////////////////////////////////////////////////////////////////////
  285. // This is the affine transformation compositon function. It's RES=(A(B))  //
  286. /////////////////////////////////////////////////////////////////////////////
  287.  
  288. AFFIN aff_mul_aff(AFFIN a, AFFIN b)
  289. {
  290.  AFFIN res;
  291.  res.aff_mtx=mtx_mul_mtx(a.aff_mtx,b.aff_mtx);
  292.  res.aff_vtr=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b.aff_vtr),a.aff_vtr);
  293.  return(res);
  294. }
  295.  
  296. AFFIN AxA(AFFIN a, AFFIN b)
  297. {
  298.  AFFIN res;
  299.  res.aff_mtx=mtx_mul_mtx(a.aff_mtx,b.aff_mtx);
  300.  res.aff_vtr=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b.aff_vtr),a.aff_vtr);
  301.  
  302.  return(res);
  303. }
  304.  
  305. VECTOR AxV(AFFIN a, VECTOR b)
  306. {
  307.  VECTOR res;
  308.  res=vtr_add_vtr(mtx_mul_vtr(a.aff_mtx,b),a.aff_vtr);
  309.  return(res);
  310. }
  311.  
  312. IMPLICIT_PLANE calc_plane(VECTOR a, VECTOR b, VECTOR c)
  313. {
  314.  IMPLICIT_PLANE res;
  315.  res.normal=unit_vtr(vtr_cross_mul_vtr(vtr_sub_vtr(b,a),vtr_sub_vtr(c,a)));
  316.  res.d=-vtr_dot_mul_vtr(res.normal,c);
  317.  return(res);
  318. }
  319.  
  320. VECTOR calc_normal(VECTOR a, VECTOR b, VECTOR c)
  321. {
  322.  VECTOR res;
  323.  res=unit_vtr(vtr_cross_mul_vtr(vtr_sub_vtr(b,a),vtr_sub_vtr(c,a)));
  324.  return(res);
  325. }
  326.  
  327. float dist_to_plane(IMPLICIT_PLANE p, VECTOR v)
  328. {
  329.  return (vtr_dot_mul_vtr(p.normal,v)+p.d);
  330. }
  331.